/*
 * Copyright 2007-2009 Thomas Krause (thomas@berlin-reloaded.de)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gidoo.cms.admin.addins;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.model.StringResourceModel;
import org.gidoo.cms.admin.AdminPage;
import org.gidoo.cms.login.GidooCMSSession;

/**
 * A panel where you can adminstrate a single section.
 * @author <a href="mailto:thomas@berlin-reloaded.de">Thomas Krause</a>
 */
public class SingleSectionPanel extends AddInPanel
{

  private Form formDelete;
  private Button btDelete;
  private Form formOrder;
  private Form formChange;
  private TextField<String> txtURL;
  private TextField<String> txtName;
  private String theSection;
  private AdminPage theParent;

  /**
   * Creates a new instance of UsersPanel
   * @param id The wicket id.
   * @param section The name of the section.
   */
  public SingleSectionPanel(String id, String section, AdminPage parent)
  {
    super(id);
    this.theSection = section;
    this.theParent = parent;

    formChange = new Form("formChange");
    txtURL = new TextField<String>("txtURL", new Model(""));
    txtName = new TextField<String>("txtName", new Model(""));

    formChange.add(new Button("btChange", new ResourceModel("change"))
    {

      @Override
      public void onSubmit()
      {
        try
        {
          String url = txtURL.getModelObject();
          String name = txtName.getModelObject();

          GidooCMSSession gs = (GidooCMSSession) getSession();
          Node rootNode = gs.getJcrRootNode();
          Session session = gs.getJcrSession();

          Node sectionsNode = rootNode.getNode("sections");
          String oldURL =
            sectionsNode.getNode(theSection).getProperty("cms:url").getString();

          boolean canBeUpdated = true;
          if(!oldURL.equals(url))
          {
            QueryResult r = gs.getQueryManager().createQuery(
              "/jcr:root/sections/*[@cms:url = '" + url + "']", Query.XPATH).execute();
            if(r.getNodes().hasNext())
            {
              canBeUpdated = false;
            }
          }

          if(!theSection.equals(name))
          {
            if(sectionsNode.hasNode(name))
            {
              canBeUpdated = false;
            }
          }

          if(!canBeUpdated)
          {
            error(getString("alreadyexists"));
          }
          else
          {
            session.getWorkspace().move("/sections/" + theSection, "/sections/" + name);
            Node newNode = sectionsNode.getNode(name);
            newNode.setProperty("cms:url", url == null ? "" : url);

            newNode.save();

            // update all references (publishing and editing rights)
            QueryManager qm = session.getWorkspace().getQueryManager();
            QueryResult rEdit = qm.createQuery("/jcr:root/users/*/edit/" + theSection, Query.XPATH).execute();
            NodeIterator it = rEdit.getNodes();

            while(it.hasNext())
            {
              Node n = it.nextNode();
              session.getWorkspace().move(n.getPath(), n.getParent().getPath() + "/" + name);
            }

            QueryResult rPublish = qm.createQuery("/jcr:root/users/*/publish/" + theSection, Query.XPATH).execute();
            it = rPublish.getNodes();

            while(it.hasNext())
            {
              Node n = it.nextNode();
              session.getWorkspace().move(n.getPath(), n.getParent().getPath() + "/" + name);
            }
            theSection = name;
          }

          updateDataAndView();
          theParent.setSelectedNode(theParent.getSectionNode());
          theParent.updateDataAndView();
        }
        catch(RepositoryException ex)
        {
          Logger.getLogger(SingleSectionPanel.class.getName()).log(Level.SEVERE, null, ex);
          error(getString("jcrerror"));
        }
      }
    });

    formChange.add(txtName);
    formChange.add(txtURL);
    add(formChange);
    updateDataAndView();

    formDelete = new Form("formDelete");
    btDelete = new Button("btDelete", new ResourceModel("deleteSection"))
    {
      @Override
      public void onSubmit()
      {
        try
        {
          GidooCMSSession session = (GidooCMSSession) getSession();

          // delete all references (publishing and editing rights)
          QueryManager qm = session.getJcrSession().getWorkspace().getQueryManager();
          QueryResult rEdit = qm.createQuery("/jcr:root/users/*/edit/" + theSection, Query.XPATH).execute();
          NodeIterator it = rEdit.getNodes();

          while(it.hasNext())
          {
            it.nextNode().remove();
          }
          QueryResult rPublish = qm.createQuery("/jcr:root/users/*/publish/" + theSection, Query.XPATH).execute();
          it = rPublish.getNodes();

          while(it.hasNext())
          {
            it.nextNode().remove();
          }

          Node sectionsNode = session.getJcrRootNode().getNode("sections");
          sectionsNode.getNode(theSection).remove();

          session.getJcrSession().save();

          theParent.setSelectedNode(null);
          theParent.updateDataAndView();
        }
        catch(RepositoryException ex)
        {
          Logger.getLogger(SingleSectionPanel.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
          error(getString("jcrerror"));
        }
      }
    };

    formDelete.add(btDelete);
    add(formDelete);

    formOrder = new Form("formOrder");
    AjaxButton btUp = new AjaxButton("btUp")
    {
      @Override
      protected void onSubmit(AjaxRequestTarget target, Form form)
      {
        sectionUp();
        target.addComponent(theParent.getTreeNav());
        target.addComponent(feedback);
      }
    };

    btUp.setModel(new ResourceModel("up"));
    formOrder.add(btUp);

    AjaxButton btDown = new AjaxButton("btDown")
    {
      @Override
      protected void onSubmit(AjaxRequestTarget target, Form form)
      {
        sectionDown();

        target.addComponent(theParent.getTreeNav());
        target.addComponent(feedback);
      }
    };

    btDown.setModel(new ResourceModel("down"));
    formOrder.add(btDown);
    add(formOrder);
  }

  private void sectionUp()
  {
    try
    {
      if(theSection == null)
      {
        return;
      }

      Node sNode = ((GidooCMSSession) getSession()).getJcrRootNode().getNode("sections");
      NodeIterator it = sNode.getNodes();
      
      Node lastNode = null;

      while(it.hasNext())
      {
        Node c = it.nextNode();

        if(c.getName().equals(theSection))
        {
          if(lastNode != null)
          {
            sNode.orderBefore(theSection, lastNode.getName());
            sNode.save();
          }
          break;
        }
        else
        {
          lastNode = c;
        }
      }

      theParent.updateTreeModel(null, theSection);
    }
    catch(RepositoryException ex)
    {
      Logger.getLogger(SingleSectionPanel.class.getName()).log(Level.SEVERE, null, ex);
      error(getString("jcrerror"));
    }
  }

  private void sectionDown()
  {
    try
    {
      if(theSection == null)
      {
        return;
      }

      Node sNode = ((GidooCMSSession) getSession()).getJcrRootNode().getNode("sections");
      NodeIterator it = sNode.getNodes();

      while(it.hasNext())
      {
        Node c = it.nextNode();
        if(c.getName().equals(theSection))
        {
          if(it.hasNext())
          {
            sNode.orderBefore(it.nextNode().getName(), theSection);
            sNode.save();
          }
          break;
        }
      }

      theParent.updateTreeModel(null, theSection);
    }
    catch(RepositoryException ex)
    {
      Logger.getLogger(SingleSectionPanel.class.getName()).log(Level.SEVERE, null, ex);
      error(getString("jcrerror"));
    }

  }

  private void updateDataAndView()
  {
    try
    {
      StringResourceModel rm =
        new StringResourceModel("title", this, new Model<String>(""),
          new Object[] {theSection});
      lblTitle.setDefaultModel(rm);
      
      Node s = ((GidooCMSSession) getSession()).getJcrRootNode().getNode("sections").getNode(theSection);
      txtName.setModelObject(theSection);
      txtURL.setModelObject(s.getProperty("cms:url").getString());
    }
    catch(RepositoryException ex)
    {
      Logger.getLogger(SingleSectionPanel.class.getName()).log(Level.SEVERE, null, ex);
    }
  }
}

